﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace ConjureBivouac2012.Sprites
{
    public class Sprite
    {
        #region Attributes

        private Vector2 _origin = new Vector2(0, 0);

        //The current position of the Sprite
        private Vector2 _position = new Vector2(-1, -1);

        //The texture object used when drawing the sprite
        private Texture2D _spriteTexture;

        //The Rectangular area from the original image that defines the Sprite.
        private Rectangle _source;

        //The size of the Sprite (with scale applied)
        private Rectangle _size;

        //Used to size the Sprite up or down from the original image
        private float _scale = 1.0f;

        protected float _alphaValue = 0.0f;
        protected float _depth = 0.5f;
        protected float _rotation = 0.0f;

        public Rectangle Source
        {
            get { return _source; }
            set
            {
                _source = value;
                _size = new Rectangle(0, 0, (int)(_source.Width * Scale), (int)(_source.Height * Scale));

                if(DefaultOrigin)
                {
                    _origin = new Vector2((float)_source.Width/2, (float)_source.Height/2);
                }
            }
        }

        public bool DefaultOrigin;

        public Sprite()
        {
            DefaultOrigin = true;
        }

        private Color _spriteColor = Color.White;
        public Color SpriteColor
        {
            get { return _spriteColor; }
            set { _spriteColor = value; }
        }

        public Texture2D Texture
        {
            get { return _spriteTexture; }
            set { _spriteTexture = value; }
        }

        public float Alpha
        {
            get { return _alphaValue; }
            set { _alphaValue = value; }
        }

        public float Depth
        {
            get { return _depth; }
            set { _depth = value; }
        }

        public float Rotation
        {
            get { return _rotation; }
            set
            {
                //Rotation is always a positive number between 0 and 6.28318
                float v = value;
                if (Math.Abs(v) >= 2 * Math.PI)
                {
                    v = v % (float)(2 * Math.PI);
                }

                if (v < 0)
                {
                    v = (float)(2 * Math.PI) + v;
                }

                _rotation = v;
            }
        }

        public virtual Vector2 Position
        {
            get { return _position; }
            set { _position = value; }
        }

        public void setPosition(float x, float y)
        {
            Position = new Vector2(x, y);
        }

        public void setPosition(Vector2 v)
        {
            Position = v;
        }

        public BoundingBox Bounds
        {
            get
            {
                return new BoundingBox(new Vector3(Position.X - Size.Width / 2, Position.Y - Size.Height / 2, 0),
                    new Vector3(Position.X + Size.Width / 2, Position.Y + Size.Height / 2, 0));
            }
        }

        public Rectangle Size
        {
            get { return _size; }
        }

        //When the scale is modified throught he property, the Size of the
        //sprite is recalculated with the new scale applied.
        public float Scale
        {
            get { return _scale; }
            set
            {
                _scale = value;
                //Recalculate the Size of the Sprite with the new scale
                if (_source == null)
                {
                    _size = new Rectangle(0, 0, (int)(_spriteTexture.Width * Scale), (int)(_spriteTexture.Height * Scale));
                }
                else
                {
                    _size = new Rectangle(0, 0, (int)(_source.Width * Scale), (int)(_source.Height * Scale));
                }
            }
        }

        #endregion

        //Load the texture for the sprite using the Content Pipeline
        public virtual void LoadContent(ContentManager theContentManager, string theAssetName)
        {
            _spriteTexture = theContentManager.Load<Texture2D>(theAssetName);
            Source = new Rectangle(0, 0, _spriteTexture.Width, _spriteTexture.Height);
            _origin = new Vector2((float)_source.Width / 2, (float)_source.Height / 2);
            _size = new Rectangle(0, 0, (int)(_source.Width * Scale), (int)(_source.Height * Scale));
        }

        //Draw the sprite to the screen
        public virtual void Draw(SpriteBatch theSpriteBatch)
        {
            theSpriteBatch.Draw(_spriteTexture, Position, Source, Color.Lerp(SpriteColor, Color.Transparent, _alphaValue),
                _rotation, _origin, Scale, SpriteEffects.None, _depth);
        }
    }
}
